package com.cloudinnov.exception;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import com.alibaba.fastjson.JSON;
import com.cloudinnov.utils.CommonUtils;

@EnableWebMvc
@ControllerAdvice
public class ApiExceptionHandler {
	private static final Logger logger = LoggerFactory.getLogger(ApiExceptionHandler.class);

	@ExceptionHandler(BindException.class)
	@ResponseStatus(value = HttpStatus.BAD_REQUEST)
	@ResponseBody
	public String handleInvalidRequestError(BindException ex) {
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, Object> params = new HashMap<String, Object>();
		List<FieldError> list = ex.getFieldErrors();
		for (FieldError error : list) {
			params.put(error.getField(), error.getRejectedValue());
		}
		if (logger.isDebugEnabled()) {
			map.put("data", params);
		}
		map.put("code", CommonUtils.PARAMETER_EXCEPTION_CODE);
		map.put("msg", CommonUtils.PARAMETER_EXCEPTION_MSG);
		map.put("success", false);
		logger.error("BindException", ex);
		return JSON.toJSONString(map);
	}
	@ExceptionHandler(NumberFormatException.class)
	@ResponseStatus(value = HttpStatus.BAD_REQUEST)
	@ResponseBody
	public String handleInvalidNumberFormatExceptionRequestError(NumberFormatException ex, HttpServletRequest request) {
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, String[]> map = request.getParameterMap();
		Set<Entry<String, String[]>> set = map.entrySet();
		Iterator<Entry<String, String[]>> it = set.iterator();
		while (it.hasNext()) {
			Entry<String, String[]> entry = it.next();
			for (String i : entry.getValue()) {
				params.put(entry.getKey(), i);
			}
		}
		Map<String, Object> data = new HashMap<String, Object>();
		if (logger.isDebugEnabled()) {
			data.put("data", params);
		}
		data.put("code", CommonUtils.NUMBERFORMAT_EXCEPTION_CODE);
		data.put("msg", CommonUtils.NUMBERFORMAT_EXCEPTION_MSG);
		data.put("success", false);
		logger.error("NumberFormatException", ex);
		return JSON.toJSONString(map);
	}
	
	@ExceptionHandler(RuntimeException.class)
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
	@ResponseBody
	public String handleUnexpectedServerError(RuntimeException ex) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", CommonUtils.SYSTEM_EXCEPTION_CODE);
		map.put("msg", CommonUtils.SYSTEM_EXCEPTION_MSG);
		map.put("success", false);
		if (logger.isDebugEnabled()) {
			map.put("data", ex.getMessage());
		}
		logger.error("RuntimeException", ex);
		return JSON.toJSONString(map);
	}
}
